#ifndef DATAMAN_H
#define DATAMAN_H

#include <QObject>
#include <QVariant>
#define DM_PROPERTY(t, n)  Q_PROPERTY(t n READ n WRITE set##n)
#define DM_PROPERTY_NOTIFY(t, n) Q_PROPERTY(t n READ n WRITE set##n NOTIFY n##Changed)
#define DM_PROPERTY_FUNC(t, n) \
	inline t n() const { return d.n;} \
	inline void set##n(t k) { d.n = k;}

#define DM_PROPERTY_NOTIFY_FUNC(t, n) \
	inline t n() const { return d.n;} \
	inline void set##n(t k) {d.n = k; emit n##Changed();}

class DataMan : public QObject
{
	Q_OBJECT
	DM_PROPERTY(bool, firstPlay)
	DM_PROPERTY(bool, music)
	DM_PROPERTY_NOTIFY(uint, lv)
	DM_PROPERTY_NOTIFY(uint, nowSc)
	DM_PROPERTY_NOTIFY(uint, highSc)
	Q_PROPERTY(QVariantList garr READ garr WRITE setgarr)
	Q_PROPERTY(QVariantList propN READ propN WRITE setpropN)
	Q_ENUMS(MonsterT PropT)

public:
	enum MonsterT { MNONE, MG, MR, MB, MP, MY};		// 小怪兽的样式
	enum PropT { PNONE = -1, PDSc, PHar, PRe, PZom, PHeart};// 道具的种类
	static const int ROW = 8;
	static const int COL = 8;
	static const int MonsterTypeN = MY;
	static const int PropTypeN = PHeart + 1;

	struct Data {
		int32_t		magic;		// 验证位
		int16_t		version;	// 数据版本
		bool		firstPlay;	// 第一次玩游戏
		bool		music;		// 音乐音效的开关
		int8_t		garr[COL * ROW];// 游戏时小怪兽的排布
		uint		propN[PropTypeN];
		uint		highSc;		// 最高分
		uint		nowSc;		// 当下得分
		uint		lv;		// 当前关卡
	} d;
signals:
	void nowScChanged();
	void lvChanged();
	void highScChanged();
public:
	DM_PROPERTY_FUNC(bool, firstPlay)
	DM_PROPERTY_FUNC(bool, music)
	DM_PROPERTY_NOTIFY_FUNC(uint, lv)
	DM_PROPERTY_NOTIFY_FUNC(uint, nowSc)
	DM_PROPERTY_NOTIFY_FUNC(uint, highSc)
	QVariantList		garr() const ;
	void			setgarr(const QVariantList& in);
	QVariantList		propN() const ;
	void			setpropN(const QVariantList& in);
public:
	static DataMan*		instance();
	void 			load();
	Q_INVOKABLE bool	save();
	Q_INVOKABLE inline void	reset() {reset(false);}
private:
	explicit DataMan();
	void			reset(bool first);
	QByteArray		m_hash;
};

#endif // DATAMAN_H
